package com.lqf.compare.mysql;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Controller
@EnableAsync
public class CompareController {
    
    private static final Logger logger = LoggerFactory.getLogger(CompareController.class);

    @Autowired
    private DatabaseCompareService compareService;

    @GetMapping("/")
    public String showForm(Model model, HttpSession session) {
        // 清除会话中的连接信息
        session.removeAttribute("dbConnectionInfo");
        
        model.addAttribute("hasDifference", Boolean.FALSE);
        model.addAttribute("masterDbUrl", "");
        model.addAttribute("targetDbUrl", "");
        model.addAttribute("masterUsername", "");
        model.addAttribute("targetUsername", "");
        model.addAttribute("tableName", "");
        model.addAttribute("fullCompare", Boolean.FALSE);
        return "compare"; // 返回 templates/compare.html
    }

    @PostMapping("/compare")
    public String compareTables(
            @RequestParam("masterDbUrl") String masterDbUrl,
            @RequestParam("targetDbUrl") String targetDbUrl,
            @RequestParam("masterUsername") String masterUsername,
            @RequestParam("masterPassword") String masterPassword,
            @RequestParam("targetUsername") String targetUsername,
            @RequestParam("targetPassword") String targetPassword,
            @RequestParam(value = "tableName", required = false) String tableName,
            @RequestParam(value = "fullCompare", required = false) String fullCompare,
            @RequestParam("action") String action,
            Model model, HttpSession session) {

        // 将连接信息存储到会话中
        Map<String, String> dbConnectionInfo = new HashMap<>();
        dbConnectionInfo.put("masterDbUrl", masterDbUrl);
        dbConnectionInfo.put("targetDbUrl", targetDbUrl);
        dbConnectionInfo.put("masterUsername", masterUsername);
        dbConnectionInfo.put("masterPassword", masterPassword);
        dbConnectionInfo.put("targetUsername", targetUsername);
        dbConnectionInfo.put("targetPassword", targetPassword);
        if (tableName != null && !tableName.isEmpty()) {
            dbConnectionInfo.put("tableName", tableName);
        }
        session.setAttribute("dbConnectionInfo", dbConnectionInfo);

        boolean isFullCompare = "全量对比".equals(action) || "true".equals(fullCompare);
        model.addAttribute("fullCompare", isFullCompare);

        long startTime = System.currentTimeMillis();
        
        Map<String, Object> result;
        try {
            if (isFullCompare && (tableName == null || tableName.isEmpty())) {
                // 全量对比
                result = compareService.compareAllTables(
                        masterDbUrl, targetDbUrl, masterUsername, masterPassword, targetUsername, targetPassword);
            } else {
                // 单表对比
                result = compareService.compareTableStructure(
                        masterDbUrl, targetDbUrl, masterUsername, masterPassword, targetUsername, targetPassword, tableName);
            }
        } catch (Exception e) {
            logger.error("数据库对比过程中发生异常", e);
            result = new HashMap<>();
            result.put("error", "数据库对比过程中发生异常: " + e.getMessage());
        }

        long endTime = System.currentTimeMillis();
        logger.info("数据库对比完成，耗时: {} ms", (endTime - startTime));
        
        // 如果结果中包含执行时间信息，记录到日志
        if (result.containsKey("executionTime")) {
            logger.info("数据库对比执行时间: {}", result.get("executionTime"));
        }

        model.addAllAttributes(result);

        model.addAttribute("masterDbUrl", masterDbUrl);
        model.addAttribute("targetDbUrl", targetDbUrl);
        model.addAttribute("masterUsername", masterUsername);
        model.addAttribute("targetUsername", targetUsername);
        if (tableName != null) {
            model.addAttribute("tableName", tableName);
        }

        return "compare";
    }
    
    @GetMapping("/exportSql")
    public void exportSqlStatements(
            HttpSession session,
            HttpServletResponse response) throws IOException {
        
        // 从会话中获取连接信息
        @SuppressWarnings("unchecked")
        Map<String, String> dbConnectionInfo = (Map<String, String>) session.getAttribute("dbConnectionInfo");
        
        if (dbConnectionInfo == null) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "没有找到数据库连接信息");
            return;
        }
        
        String masterDbUrl = dbConnectionInfo.get("masterDbUrl");
        String targetDbUrl = dbConnectionInfo.get("targetDbUrl");
        String masterUsername = dbConnectionInfo.get("masterUsername");
        String masterPassword = dbConnectionInfo.get("masterPassword");
        String targetUsername = dbConnectionInfo.get("targetUsername");
        String targetPassword = dbConnectionInfo.get("targetPassword");
        String tableName = dbConnectionInfo.get("tableName");
        
        Map<String, Object> result;
        if (tableName == null || tableName.isEmpty()) {
            // 全量对比
            result = compareService.compareAllTables(
                    masterDbUrl, targetDbUrl, masterUsername, masterPassword, targetUsername, targetPassword);
        } else {
            // 单表对比
            result = compareService.compareTableStructure(
                    masterDbUrl, targetDbUrl, masterUsername, masterPassword, targetUsername, targetPassword, tableName);
        }
        
        response.setContentType("text/plain; charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=\"alter_statements.sql\"");
        
        logger.info("导出SQL语句，结果键: {}", result.keySet());
        logger.info("是否存在差异: {}", result.get("hasDifference"));
        
        if (result.containsKey("alterSqlStatements")) {
            @SuppressWarnings("unchecked")
            List<String> sqlStatements = (List<String>) result.get("alterSqlStatements");
            logger.info("SQL语句数量: {}", sqlStatements.size());
            for (String sql : sqlStatements) {
                response.getWriter().println(sql);
            }
        } else if (result.containsKey("tableDifferences")) {
            // 处理全量对比的SQL导出
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> tableDifferences = (List<Map<String, Object>>) result.get("tableDifferences");
            for (Map<String, Object> tableDiff : tableDifferences) {
                if (tableDiff.containsKey("alterSqlStatements")) {
                    @SuppressWarnings("unchecked")
                    List<String> sqlStatements = (List<String>) tableDiff.get("alterSqlStatements");
                    response.getWriter().println("-- 表: " + tableDiff.get("tableName"));
                    for (String sql : sqlStatements) {
                        response.getWriter().println(sql);
                    }
                    response.getWriter().println(); // 添加空行分隔不同表的SQL
                }
            }
        } else {
            response.getWriter().println("-- 没有发现差异，无需修改");
        }
        response.getWriter().flush();
    }
    
    @GetMapping("/exportAllSql")
    public void exportAllSqlStatements(
            HttpSession session,
            HttpServletResponse response) throws IOException {
        
        // 从会话中获取连接信息
        @SuppressWarnings("unchecked")
        Map<String, String> dbConnectionInfo = (Map<String, String>) session.getAttribute("dbConnectionInfo");
        
        if (dbConnectionInfo == null) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "没有找到数据库连接信息");
            return;
        }
        
        String masterDbUrl = dbConnectionInfo.get("masterDbUrl");
        String targetDbUrl = dbConnectionInfo.get("targetDbUrl");
        String masterUsername = dbConnectionInfo.get("masterUsername");
        String masterPassword = dbConnectionInfo.get("masterPassword");
        String targetUsername = dbConnectionInfo.get("targetUsername");
        String targetPassword = dbConnectionInfo.get("targetPassword");
        
        // 全量对比
        Map<String, Object> result = compareService.compareAllTables(
                masterDbUrl, targetDbUrl, masterUsername, masterPassword, targetUsername, targetPassword);
        
        response.setContentType("text/plain; charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=\"all_alter_statements.sql\"");
        
        if (result.containsKey("tableDifferences")) {
            // 处理全量对比的SQL导出
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> tableDifferences = (List<Map<String, Object>>) result.get("tableDifferences");
            for (Map<String, Object> tableDiff : tableDifferences) {
                if (tableDiff.containsKey("alterSqlStatements")) {
                    @SuppressWarnings("unchecked")
                    List<String> sqlStatements = (List<String>) tableDiff.get("alterSqlStatements");
                    response.getWriter().println("-- 表: " + tableDiff.get("tableName"));
                    for (String sql : sqlStatements) {
                        response.getWriter().println(sql);
                    }
                    response.getWriter().println(); // 添加空行分隔不同表的SQL
                }
            }
        } else {
            response.getWriter().println("-- 没有发现差异，无需修改");
        }
        response.getWriter().flush();
    }
    
    @GetMapping("/exportTableSql")
    public void exportTableSqlStatements(
            @RequestParam String tableName,
            HttpSession session,
            HttpServletResponse response) throws IOException {
        
        // 从会话中获取连接信息
        @SuppressWarnings("unchecked")
        Map<String, String> dbConnectionInfo = (Map<String, String>) session.getAttribute("dbConnectionInfo");
        
        if (dbConnectionInfo == null) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "没有找到数据库连接信息");
            return;
        }
        
        String masterDbUrl = dbConnectionInfo.get("masterDbUrl");
        String targetDbUrl = dbConnectionInfo.get("targetDbUrl");
        String masterUsername = dbConnectionInfo.get("masterUsername");
        String masterPassword = dbConnectionInfo.get("masterPassword");
        String targetUsername = dbConnectionInfo.get("targetUsername");
        String targetPassword = dbConnectionInfo.get("targetPassword");
        
        // 单表对比
        Map<String, Object> result = compareService.compareTableStructure(
                masterDbUrl, targetDbUrl, masterUsername, masterPassword, targetUsername, targetPassword, tableName);
        
        response.setContentType("text/plain; charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=\"alter_statements_" + tableName + ".sql\"");
        
        if (result.containsKey("alterSqlStatements")) {
            @SuppressWarnings("unchecked")
            List<String> sqlStatements = (List<String>) result.get("alterSqlStatements");
            for (String sql : sqlStatements) {
                response.getWriter().println(sql);
            }
        } else {
            response.getWriter().println("-- 没有发现差异，无需修改");
        }
        response.getWriter().flush();
    }
}